package cn.wolfcode.shiro;

import cn.wolfcode.domain.User;
import cn.wolfcode.mapper.DataMapper;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.List;

/**
 * ClassName UserRealm
 * Create by Mike
 * Date 2021/8/15 14:08
 */
public class UserRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) throws AuthenticationException {

        //无非根据登录用户,提供其对应角色和权限数据
        //类似我们之前从session获取存入的对象
        User user = (User) principals.getPrimaryPrincipal();
        String username = user.getUsername();
        //获取用户对应角色
        List<String> roles = DataMapper.getRoleByName(username);
        //获取用户对应权限
        List<String> permissions = DataMapper.getPermissionByName(username);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roles);
        info.addStringPermissions(permissions);
        return info;

    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 页面传入的账号
        String userName = (String) token.getPrincipal();
        // 模拟从数据库中查询数据
        User user = DataMapper.getUserByName(userName);
        if(user == null) {
            // 账号不存在则返回 NULL
            return null;
        } else {
            // 如果存在需要封装成 AuthenticationInfo 对象返回
            return new SimpleAuthenticationInfo(
                    // 身份对象，可以理解为在 Web 环境中登录成功后需要放入 Session 中的对象
                    user,
                    // 凭证（密码），需要和传入的凭证（密码）做比对
                    user.getPassword(),
                    // 返回盐
                    ByteSource.Util.bytes(user.getSalt()),
                    // 当前 Realm 的名称，暂时无用，不需纠结
                    this.getName());
        }
    }
}
